//
//  NetWorkManager.m
//  game
//
//  Created by 马凌云 on 2018/3/7.
//  Copyright © 2018年 YD. All rights reserved.
//

#import "NetWorkManager.h"
#import "AFNetworking.h"
#import "HashEncryption.h"

/**
 * 错误码
 */

typedef NS_ENUM(NSInteger,ErrorCode) {
    ErrorCodeNotReachable = 700,// 没有网络
};

// 请求超时时长
static const CGFloat NWTimeout = 30;
// 缓存文件夹
static NSString * const YNetworkFileCahce = @"YNetworkFileCahce";

@implementation NetWorkManager

/**
 * 初始化manager
 */
+ (AFHTTPSessionManager *)initManager{
    
    NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration];
    // 内存4m,硬盘30m
    NSURLCache* cache = [[NSURLCache alloc] initWithMemoryCapacity:4*1024*1024 diskCapacity:30*1024*1024 diskPath:nil];
    [config setURLCache:cache];
    
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:config];
    
    // 设置响应序列化器，解析Json对象
    AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer];// json 解析器
    responseSerializer.removesKeysWithNullValues = YES; // 清除返回数据的 NSNull
    responseSerializer.acceptableContentTypes = [NSSet setWithObjects:  @"application/x-javascript", @"application/json", @"text/json", @"text/javascript", @"text/html", @"text/plain",nil]; // 设置接受数据的格式
    manager.responseSerializer = responseSerializer;
    
    // 设置请求序列化器
    manager.requestSerializer.timeoutInterval = NWTimeout;// 设置请求超时时长
    
    // 开启网络检测
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
    
    return manager;
}

/**
 *  get请求
 *
 *  @param url          url
 *  @param completion   block回调，包含responseObject和error
 *
 */
+ (void)getRequestForUrl:(NSString *)url completion:(void (^)(id responseObject, NSError *error))completion{
    
    AFHTTPSessionManager *manager = [self initManager];// 初始化 sessionManager
    
    //没有网络，返回无网络
    if([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus == AFNetworkReachabilityStatusNotReachable){
        NSError *error = [NSError errorWithDomain:@"没有网络" code:ErrorCodeNotReachable userInfo:nil];
        completion(nil,error);
        return;
    }
    
    
    [manager GET:url parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        completion(responseObject,nil);
        [manager.session invalidateAndCancel];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        completion(nil,error);
        [manager.session invalidateAndCancel];
    }];
}


+ (void)postRequestForUrl:(NSString *)url params:(NSDictionary *)params extend:(NetWorkExtend *)extend completion:(void (^)(id responseObject, NSError *error))completion {
    
    [self postRequestForUrl:url params:params extend:extend cache:nil completion:completion];
}

/**
 *  post请求
 *
 *  @param url          url
 *  @param params       参数
 *  @param extend       extend,扩展数据
 *  @param cache        cache回调，包含responseObject
 *  @param completion   block回调，包含responseObject和error
 *
 */
+ (void)postRequestForUrl:(NSString *)url params:(NSDictionary *)params extend:(NetWorkExtend *)extend cache:(void (^) (id responseObject))cache completion:(void (^)(id responseObject, NSError *error))completion{
    // 返回缓存数据
    NSString *backKey;
    if (extend.type) {
        backKey = [NSString stringWithFormat:@"%@%@",url,extend.type];
    } else {
        backKey = url;
    }
    id backObject = [self readDataFileWithKey:backKey];
    if (cache) {
        cache(backObject);
    }
    
    
    AFHTTPSessionManager *manager = [self initManager];// 初始化 sessionManager
    
    //没有网络，返回无网络
    if([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus == AFNetworkReachabilityStatusNotReachable){
        NSError *error = [NSError errorWithDomain:@"没有网络" code:ErrorCodeNotReachable userInfo:nil];
        completion(nil,error);
        return;
    }
    
    [manager POST:url parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        completion(responseObject,nil);
        [manager.session invalidateAndCancel];
        // 缓存
        if (extend && extend.isCache == YES) {
            NSString *key;
            if (extend.type) {
                key = [NSString stringWithFormat:@"%@%@",url,extend.type];
            } else {
                key = url;
            }
            [self saveDataFileWithResData:responseObject key:key];
        }
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        completion(nil,error);
        [manager.session invalidateAndCancel];
    }];
    
}

#pragma mark -- 缓存

// 归档缓存数据
+ (void)saveDataFileWithResData:(id)resData key:(NSString *)key{
    
    NSLock *lock = [NSLock new];
    [lock lock];
    
    NSString *cachePath = [self cacheFilePath:key];
    [NSKeyedArchiver archiveRootObject:resData toFile:cachePath];
    [lock unlock];
    
}

// 解档读取数据,注意扩展里的type
+ (id)readDataFileWithKey:(NSString *)key{
    
    NSLock *lock = [NSLock new];
    [lock lock];
    
    NSString *cachePath = [self cacheFilePath:key];
    id resData = [NSKeyedUnarchiver unarchiveObjectWithFile:cachePath];
    [lock unlock];
    return resData;
    
}

// 缓存路径
+ (NSString *)cacheFilePath:(NSString *)path{
    NSString *cachePath = [HashEncryption md5Hash:path];
    return [[self cacheBasePath] stringByAppendingPathComponent:cachePath];
}


// 缓存基础路径
+ (NSString *)cacheBasePath{
    
    NSString *libCachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject;
    NSString *path = [libCachePath stringByAppendingPathComponent:YNetworkFileCahce];
    if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {// 不存在该目录
        [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
    }
    return path;
}

@end
